#include "../lib/Partie.hpp"


#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <time.h>
#include <fstream>
#include <cstring>

const int NB_JOUEURS = 2;

using namespace std;


void Init_Partie ( Partie * P)
{

    P->Jhumain = NULL;
    P->IA = NULL;
    P->C= new Carte;
    Init_Carte ( *P->C );
    Init_Carte_Fichier(*P->C);

}

Partie * Creer_Partie()
{
    Partie * P = new Partie;
    Init_Partie (P);

    P->Jhumain = Alloue_Joueur();
    P->IA = Alloue_Joueur();

    unsigned int xj,yj,xia,yia;

    srand (time(NULL));

    xj = rand()%12;
    yj = rand()%2;
    xia = rand()%12;
    yia = rand()%2 + 10;

    while ( P->C->CARTE[yj+xj*P->C->taille] == mer)
    {
        xj = rand()%12;
        yj = rand()%2;
    }
    while ( P->C->CARTE[yia+xia*P->C->taille] == mer)
    {
        xia = rand()%12;
        yia = rand()%2+10;
    }


    Unite * ColonJ = Creer_Unite(P->Jhumain,xj,yj);
    Creer_Colon (ColonJ);


    Unite * ColonIA = Creer_Unite(P->IA,xia,yia);
    Creer_Colon (ColonIA);


    return P;
}

Partie * Charger_Partie()
{
    Partie * P = Charge_Partie();

    return P;
}

void Testament_Partie ( Partie * P)
{
    Testament_Carte(*P->C);

    Testament_Joueur (P->Jhumain);
    Testament_Joueur (P->IA);
    delete P->C;
    delete P;
}

void Sauvegarde_Partie ( Partie * P)
{
    Unite* temp;
    Ville* temp_ville;
    ofstream fichier("data/sauvegardes/civsave.txt",ios::out | ios::trunc );  // on ouvre le fichier en ecriture

    if(fichier)  // si l'ouverture a réussi
    {
        fichier << 2 <<endl; // pour l'instant nous sommes fixé à deux
/*****************************************************/
        fichier << P->Jhumain->nb_unite << endl;
        for ( unsigned int i = 0 ; i <  P->Jhumain->nb_unite ; i++)
        {
            temp= P->Jhumain->tab_unite[i];
            fichier << temp->nom << " "<<temp->pos->x <<" "<< temp->pos->y <<" "<< temp->pdv << endl;
        }

        fichier << P->IA->nb_unite << endl;
        for ( unsigned int i = 0 ; i <  P->IA->nb_unite ; i++)
        {
            temp= P->IA->tab_unite[i];
            fichier << temp->nom << " "<<temp->pos->x <<" "<< temp->pos->y <<" "<< temp->pdv << endl;
        }
/***********************************************/
        fichier << P->Jhumain->nb_ville << endl;
        for ( unsigned int i = 0 ; i <  P->Jhumain->nb_ville ; i++)
        {
            temp_ville= P->Jhumain->tab_ville[i];
            fichier << temp_ville->pos->x << " "<<temp_ville->pos->y<< endl;
        }

        fichier << P->IA->nb_ville << endl;
        for ( unsigned int i = 0 ; i <  P->IA->nb_ville ; i++)
        {
            temp_ville= P->IA->tab_ville[i];
            fichier << temp_ville->pos->x << " "<<temp_ville->pos->y << endl;
        }



    }

    fichier.close();


}

Partie * Charge_Partie ( )
{
    int NB_joueurs,x,y, pdv;
    unsigned int data;
    Unite * U;
    Ville* v;
    int temp;
    ifstream fichier("data/sauvegardes/civsave.txt", ios::in);  // on ouvre le fichier en lecture

    Partie * P = new Partie;
    Init_Partie ( P);
    //! la carte est initialisee avec

    if(fichier)  // si l'ouverture a réussi
    {
            fichier >> NB_joueurs;
            P->IA = Alloue_Joueur();
            P->Jhumain = Alloue_Joueur();

            fichier >> data;
            for (unsigned int i=0; i <  data; i++)
            {
                fichier >> temp >> x >> y>>pdv;


                U=  Creer_Unite (P->Jhumain,x,y);

                if ( (Nom)temp == colon)
                {
                    Creer_Colon (U );
                    affecte_Pdv( U, pdv);
                }
                else if ( (Nom)temp  == guerrier)
                {
                    Creer_Guerrier (U);
                    affecte_Pdv( U, pdv);
                }
            }


            fichier >> data;
            for (unsigned int j=0; j <  data; j++)
            {
                fichier >> temp>>x>>y>>pdv;

                U=  Creer_Unite (P->IA,x,y);

                if ( (Nom)temp == colon)
                {
                    Creer_Colon (U);
                    affecte_Pdv( U, pdv);
                }
                else if ( (Nom)temp  == guerrier)
                {
                    Creer_Guerrier (U);
                    affecte_Pdv( U, pdv);
                }
            }

            fichier>> data;
            for ( unsigned int i = 0 ; i < data; i ++)
            {
                fichier >>  x >> y;
                v = Creer_Ville ( P->Jhumain,x,y , P);
            }

            fichier>> data;
            for ( unsigned int i = 0 ; i < data; i ++)
            {
                fichier >> x >> y;
                v = Creer_Ville ( P->IA,x,y , P);
            }

    }
    fichier.close();

    return P;
}

void Demarre_Partie()
{
    Partie * P = Creer_Partie();




    SDL_Surface * ecran = NULL;

    SDL_Init(SDL_INIT_VIDEO);
    SDL_WM_SetCaption("Civilization by Quentin & BJ", NULL);
    ecran = SDL_SetVideoMode(1024, 768, 32, SDL_HWSURFACE | SDL_DOUBLEBUF);
    TTF_Init();


    Rafraichit_ecran(ecran,P);

    SDL_FreeSurface(ecran);

    Deroulement_Partie(ecran,P);


}

void Demarre_Partie_Chargee()
{
    Partie * P = Charger_Partie();




    SDL_Surface * ecran = NULL;

    SDL_Init(SDL_INIT_VIDEO);
    SDL_WM_SetCaption("Civilization by Quentin & BJ", NULL);
    ecran = SDL_SetVideoMode(1024, 768, 32, SDL_HWSURFACE | SDL_DOUBLEBUF);
    TTF_Init();


    Rafraichit_ecran(ecran,P);

    SDL_FreeSurface(ecran);

    Deroulement_Partie(ecran,P);



}

int Evenements_Ville()
{
    int continuer = 0;
    SDL_Event event;

     while (continuer == 0)
        {
            SDL_WaitEvent(&event);
            switch(event.type)
            {
                case SDL_MOUSEBUTTONUP:
                    if (event.button.button == SDL_BUTTON_LEFT)
                    {
                        if((event.button.x > 768) && (event.button.x < 832) && (event.button.y > 0) && (event.button.y < 64))  // bouton Creer colon
                        {
                            continuer = 1;
                        }
                        if((event.button.x > 768) && (event.button.x < 832) && (event.button.y > 64) && (event.button.y < 128))  // bouton Creer guerrier
                        {
                            continuer = 2;
                        }
                        if((event.button.x > 768) && (event.button.x < 1024) && (event.button.y > 128) && (event.button.y < 192))  // Bouton Ne Rien faire
                        {
                            continuer = 3;
                        }
                        if((event.button.x > 768) && (event.button.x < 1024) && (event.button.y > 640) && (event.button.y < 704))  // Bouton Sauvegarder
                        {
                            continuer =  11;
                        }
                        if((event.button.x > 768) && (event.button.x < 1024) && (event.button.y > 704) && (event.button.y < 768))  // Bouton Quitter
                        {
                            continuer =  12;
                        }

                    }

                break;
                default:
                break;

            }

        }
    return continuer;
}

int Evenements_Unite()
{
    int continuer = 0;
    SDL_Event event;

    while (continuer == 0)
        {
            SDL_WaitEvent(&event);
            switch(event.type)
            {
                case SDL_MOUSEBUTTONUP:
                    if (event.button.button == SDL_BUTTON_LEFT)
                    {
                        if((event.button.x > 768) && (event.button.x < 832) && (event.button.y > 0) && (event.button.y < 64))  // bouton Creer Ville
                        {
                            continuer = 1;
                        }
                        if((event.button.x > 768) && (event.button.x < 832) && (event.button.y > 128) && (event.button.y < 192))  // bouton Deplacer gauche
                        {
                            continuer =  2;
                        }
                        if((event.button.x > 832) && (event.button.x < 896) && (event.button.y > 128) && (event.button.y < 192))  // Bouton Deplacer haut
                        {
                            continuer =  3;
                        }
                        if((event.button.x > 896) && (event.button.x < 960) && (event.button.y > 128) && (event.button.y < 192))  // Bouton Deplacer bas
                        {
                            continuer =  4;
                        }
                        if((event.button.x > 960) && (event.button.x < 1024) && (event.button.y > 128) && (event.button.y < 192))  // Bouton Deplacer droite
                        {
                            continuer =  5;
                        }
                        if((event.button.x > 768) && (event.button.x < 832) && (event.button.y > 256) && (event.button.y < 320))  // Bouton Attaquer gauche
                        {
                            continuer =  6;
                        }
                        if((event.button.x > 832) && (event.button.x < 896) && (event.button.y > 256) && (event.button.y < 320))  // Bouton Attaquer haut
                        {
                            continuer =  7;
                        }
                        if((event.button.x > 896) && (event.button.x < 960) && (event.button.y > 256) && (event.button.y < 320))  // Bouton Attaquer bas
                        {
                            continuer =  8;
                        }
                        if((event.button.x > 960) && (event.button.x < 1024) && (event.button.y > 256) && (event.button.y < 320))  // Bouton Attaquer droite
                        {
                            continuer =  9;
                        }
                        if((event.button.x > 768) && (event.button.x < 1024) && (event.button.y > 320) && (event.button.y < 384))  // Bouton Ne Rien Faire
                        {
                            continuer =  10;
                        }
                        if((event.button.x > 768) && (event.button.x < 1024) && (event.button.y > 640) && (event.button.y < 704))  // Bouton Sauvegarder
                        {
                            continuer =  11;
                        }
                        if((event.button.x > 768) && (event.button.x < 1024) && (event.button.y > 704) && (event.button.y < 768))  // Bouton Quitter
                        {
                            continuer =  12;
                        }

                    }

                break;
                default:
                break;

            }

        }
    return continuer;
}

void Tour(SDL_Surface * ecran, Partie * P, int & termine)
{
    int eventville = 0, eventunite = 0;
    Coord * C;
    Unite * U;
    Ville * V;


    if(termine != 0)
    {
        for(unsigned int i = 0; i < P->Jhumain->nb_unite ; i++)  //fait le tour de chaque unite et attend une commande pour chaque
        {
            Rafraichit_ecran(ecran,P);
            Affiche_Menu_Unite(ecran);

            U = Retourne_Unite (P->Jhumain,i);
            C = Retourne_Coord (U);
            Affiche_Cercle_Selection(ecran,C);


            eventunite = Evenements_Unite();


            switch(eventunite)
            {
                case 1:
                {
                    Colon_Cree_Ville (P->Jhumain,U,P);
                    i--;
                }

                break;
                case 2:
                    Deplacer_Unite(U,-1,0,P);
                break;
                case 3:
                    Deplacer_Unite(U,0,-1,P);
                break;
                case 4:
                    Deplacer_Unite(U,0,1,P);
                break;
                case 5:
                    Deplacer_Unite(U,1,0,P);
                break;
                case 6:
                    Attaquer_Gauche(P->Jhumain,U,P);
                break;
                case 7:
                    Attaquer_Haut(P->Jhumain,U,P);
                break;
                case 8:
                    Attaquer_Bas(P->Jhumain,U,P);
                break;
                case 9:
                    Attaquer_Droite(P->Jhumain,U,P);
                break;
                case 10:
                break;
                case 11:
                    Sauvegarde_Partie (P);
                break;
                case 12:
                {
                    termine = 0;
                    i = P->Jhumain->nb_unite;
                }
                break;
                default:
                break;
            }



        }

    }

    if(termine != 0)
    {
        for(unsigned int i = 0; i < P->Jhumain->nb_ville ; i++)  // fait le tour de chaque Ville et attend une commande pour chaque
        {
            Rafraichit_ecran(ecran,P);
            Affiche_Menu_Ville(ecran);

            V = Retourne_Ville (P->Jhumain,i);
            C = Retourne_Coord_Ville (V);
            Affiche_Cercle_Selection(ecran,C);


            eventville = Evenements_Ville();

            switch(eventville)
            {
                case 1:
                    Ville_Cree_Colon_Bas (P->Jhumain,V,P);
                break;
                case 2:
                    Ville_Cree_Guerrier_Bas (P->Jhumain,V,P);
                break;
                case 3:
                break;
                 case 11:
                    Sauvegarde_Partie (P);
                break;
                case 12:
                {
                    termine = 0;
                    i = P->Jhumain->nb_ville;
                }
                break;
                default:
                break;
            }


        }
    }

    if(termine != 0)
    {
        for(unsigned int i = 0; i < P->IA->nb_unite ; i++)  //fait le tour de chaque unite et attend une commande pour chaque
        {
            Rafraichit_ecran(ecran,P);
            Affiche_Menu_Unite_IA(ecran);

            U = Retourne_Unite (P->IA,i);
            C = Retourne_Coord (U);
            Affiche_Cercle_Selection(ecran,C);

            eventunite = Choix_IA_Unite(P,i);

            switch(eventunite)
            {
                case 1:
                    Colon_Cree_Ville (P->IA,U,P);
                break;
               case 2:
                    Deplacer_Unite(U,-1,0,P);
                break;
                case 3:
                    Deplacer_Unite(U,0,-1,P);
                break;
                case 4:
                    Deplacer_Unite(U,0,1,P);
                break;
                case 5:
                    Deplacer_Unite(U,1,0,P);
                break;
                case 6:
                    Attaquer_Gauche_IA(P->IA,U,P);
                break;
                case 7:
                    Attaquer_Haut_IA(P->IA,U,P);
                break;
                case 8:
                    Attaquer_Bas_IA(P->IA,U,P);
                break;
                case 9:
                    Attaquer_Droite_IA(P->IA,U,P);
                break;
                case 10:
                break;
                default:
                break;
            }


        }
    }


    if(termine != 0)
    {
        for(unsigned int i = 0; i < P->IA->nb_ville ; i++)  // fait le tour de chaque ville et attend une commande pour chaque
        {
            Rafraichit_ecran(ecran,P);
            Affiche_Menu_Ville_IA(ecran);

            V = Retourne_Ville (P->IA,i);
            C = Retourne_Coord_Ville (V);
            Affiche_Cercle_Selection(ecran,C);

            eventville = Choix_IA_Ville(P,i);

            switch(eventville)
            {
                case 1:
                    Ville_Cree_Colon_Haut (P->IA,V,P);
                break;
                case 2:
                    Ville_Cree_Guerrier_Haut (P->IA,V,P);
                break;
                default:
                break;
            }


        }
    }




}


void Deroulement_Partie(SDL_Surface * ecran, Partie * P)
{
    int gagne = 0;
    int termine = 1;

    Initialisation_IA(P);

    while(gagne == 0 && termine == 1)
    {

        Tour(ecran,P,termine);

        gagne = Qui_A_Gagne(P);

    }
    Testament_Partie(P);
    TTF_Quit();
    SDL_Quit();
    Choix_Lancement();
}


int Qui_A_Gagne ( Partie * P)
{
    int g = 0;

    if((P->Jhumain->nb_unite == 0) && (P->Jhumain->nb_ville == 0))
    {
        g = 2;
    }
    else if((P->IA->nb_unite == 0) && (P->IA->nb_ville == 0))
    {
        g = 1;
    }
    else
    {
        g = 0;
    }

    return g;

}

bool Coord_Deja_Utilisee (unsigned  int x, unsigned int y , Partie * P)
{
    bool b  = false;

    for( unsigned int i = 0 ; i < P->Jhumain->nb_unite ; i ++ )
    {
        if (  P->Jhumain->tab_unite[i]->pos->x == x )
        {
            if ( P->Jhumain->tab_unite[i]->pos->y == y )
            {
                b = true;
            }
        }
    }

    for( unsigned int i = 0 ; i < P->IA->nb_unite ; i ++ )
    {
        if (  P->IA->tab_unite[i]->pos->x == x )
        {
            if ( P->IA->tab_unite[i]->pos->y == y )
            {
                b = true;
            }
        }
    }

    for( unsigned int i = 0 ; i < P->Jhumain->nb_ville ; i ++ )
    {
        if (  P->Jhumain->tab_ville[i]->pos->x == x )
        {
            if ( P->Jhumain->tab_ville[i]->pos->y == y )
            {
                b = true;
            }
        }
    }

    for( unsigned int i = 0 ; i < P->IA->nb_ville ; i ++ )
    {
        if (  P->IA->tab_ville[i]->pos->x == x )
        {
            if ( P->IA->tab_ville[i]->pos->y == y )
            {
                b = true;
            }
        }
    }




    return b;
}


bool Collision (  int x, int y , Partie * P)
{
    bool b = false; //! Cas pas de colision collision.

    if ( P->C->CARTE[y+x*P->C->taille] == mer )
    {
        b = true; // Dans ce cas on cherche a aller sur une case de type "mer".
    }
    else if ( Coord_Deja_Utilisee( x, y , P ) )
    {
        b = true; // une ville ou une unite y est deja presente.
    }

    return b;
}



int Test_Regression_Partie ( )
{
    int i = 1;
    Partie * P = Creer_Partie();

    assert(P->Jhumain->tab_unite[0]->nom == colon);
    assert(P->IA->tab_unite[0]->nom == colon);

    Testament_Partie( P );
    return i;
}

